using System.Collections.Generic;
using UnityEngine;

public class TableTennisMatchController : MonoBehaviour, MatchControllerUiInteface, MatchControllerInterface
{
	public List<TableTennisPlayerBase> players = new List<TableTennisPlayerBase>();

	public bool gameDone;

	public int[] timeoutCount = new int[2];

	public TableTennisGameStartScript starter { get; protected set; }

	public PhysicsBall ball { get; protected set; }

	public TableTennisGameTypeBase gameType { get; protected set; }

	public MatchUI ui { get; protected set; }

	public TTCameraController cameraController
	{
		get
		{
			return starter.cameraController;
		}
	}

	public bool isMatchReady
	{
		get
		{
			return gameType.isMatchReady;
		}
	}

	public void SetCurrentBall(PhysicsBall ball)
	{
		this.ball = ball;
	}

	public PhysicsBall CreateBall()
	{
		PhysicsBall physicsBall = starter.CreateBall();
		physicsBall.onCollision = OnBallHitObject;
		physicsBall.onMissedServe = OnMissedServe;
		physicsBall.match = this;
		physicsBall.gameObject.SetActive(true);
		return physicsBall;
	}

	public virtual void Init(TableTennisGameStartScript starter, MatchUI ui, TableTennisGameTypeBase gameType)
	{
		this.starter = starter;
		ball = CreateBall();
		GGGameTime.gameTimescale = 1f;
		ui.Init(this, ball);
		this.ui = ui;
		this.gameType = gameType;
		if (gameType != null)
		{
			gameType.Init(this, ui, MatchParameters.InitParameters);
			StartGame();
		}
	}

	public virtual void OnMissedServe()
	{
		GGDebug.DebugLog("SINGLEPLAYER");
		gameType.OnMissedServe();
	}

	public TableTennisPlayerBase CreateHumanPlayer(int tableSide, bool canAlwaysHit)
	{
		TableTennisPlayerBase tableTennisPlayerBase = starter.CreateHumanPlayer();
		tableTennisPlayerBase.Init(players.Count, tableSide, this, canAlwaysHit);
		players.Add(tableTennisPlayerBase);
		return tableTennisPlayerBase;
	}

	public virtual TableTennisPlayerBase CreateOpponentPlayer(int tableSide, bool canAlwaysHit)
	{
		TableTennisPlayerBase tableTennisPlayerBase = starter.CreateAiPlayer();
		tableTennisPlayerBase.Init(players.Count, tableSide, this, canAlwaysHit);
		players.Add(tableTennisPlayerBase);
		return tableTennisPlayerBase;
	}

	public TableTennisPlayerBase CreateTutorialPlayer(int tableSide, bool canAlwaysHit)
	{
		TableTennisPlayerBase tableTennisPlayerBase = starter.CreateTutorialPlayer();
		tableTennisPlayerBase.Init(players.Count, tableSide, this, canAlwaysHit);
		players.Add(tableTennisPlayerBase);
		return tableTennisPlayerBase;
	}

	public virtual void PlayerWillMissShot(TableTennisPlayerBase player)
	{
		gameType.PlayerWillMissShot(player);
		if (players.Count > 1)
		{
			Other(player).OpponentWillMissShot(player);
		}
	}

	public virtual void StartGame()
	{
		GGDebug.DebugLog("Start game " + isMatchReady);
		gameType.StartMatch();
	}

	public virtual void OnPlayerChosenHitPlan(TableTennisPlayerBase player, PlayerAnimationsController.HitPlan hitPlan)
	{
		if (players.Count > 1)
		{
			Other(player).OpponentChosenHitPlan(player, hitPlan);
		}
	}

	public TableTennisPlayerBase Other(TableTennisPlayerBase player)
	{
		if (players.Count <= 1)
		{
			return null;
		}
		return players[(player.teamTag + 1) % players.Count];
	}

	public TableTennisPlayerBase GetPlayer(int teamTag)
	{
		return players[teamTag];
	}

	public virtual void StartServe(TableTennisPlayerBase player)
	{
		ball.isBallInGame = false;
		player.StartServe(ball);
		if (players.Count > 1)
		{
			Other(player).AwaitServe();
		}
	}

	public virtual void OnPlayerHitBall(TableTennisPlayerBase player, HitBallParams hitBallParams)
	{
		gameType.OnPlayerHitBall(player, new HitBallParamsPhysicsFlight
		{
			missWide = false
		});
		if (players.Count > 1)
		{
			Other(player).ReceiveBall(ball);
		}
	}

	public virtual void OnPlayerHitBall(TableTennisPlayerBase player, HitBallParamsPhysicsFlight hitBallParams)
	{
		gameType.OnPlayerHitBall(player, hitBallParams);
		if (players.Count > 1)
		{
			Other(player).ReceiveBall(ball);
		}
	}

	protected virtual void OnBallHitObject(PhysicsBall ball, Vector3 pos, Vector3 vel, HitObjectTag hitObjectTag)
	{
		if (hitObjectTag != HitObjectTag.None)
		{
			gameType.OnBallHitObject(ball, pos, vel, hitObjectTag);
		}
	}

	public virtual void AwardPoint(TableTennisGameTypeBase.AwardPointParams awardPointParams)
	{
		foreach (TableTennisPlayerBase player in players)
		{
			player.BallRemovedFromGame();
		}
		gameType.ContinueFromLastPoint(awardPointParams);
	}

	public virtual void OnSwipe(TableTennisPlayerBase player)
	{
		gameType.OnSwipe(player);
	}

	public virtual void OnGameWon(bool isPlayerWinner)
	{
		gameDone = true;
		float num = LevelSystem.instance.xpPerMatch;
		int num2 = 0;
		MultiplayerGameDone.GameParams gameParams = MultiplayerGameDone.GameParams.FromMatchParameters().SetWinnings(num2).HidePlayerStars();
		ui.gameDone.DisableButtons();
		GGPlayerSettings instance = GGPlayerSettings.instance;
		if (num > 0f)
		{
			float num3 = instance.LevelProgress();
			int num4 = instance.Level();
			string l = instance.LevelName();
			instance.walletManager.AddCurrency(CurrencyType.coins, num2);
			if (num3 < (float)instance.Level())
			{
				Analytics.instance.PlayerReachedNewLevel();
			}
			float curLevel = instance.LevelProgress();
			string l2 = instance.LevelName();
			ui.gameDone.ShowAnim(gameParams.SetWinnerIndex((!isPlayerWinner) ? 1 : 0).SetLevelNames(l, l2).SetLevels(num3, curLevel)
				.SetDelegate(delegate
				{
					GGDebug.DebugLog("Done");
					OnGameWonComplete();
				}));
			GGDebug.DebugLog("score report");
			GameNetwork.instance.reportScore(instance.Model.score);
		}
		else
		{
			float num5 = instance.LevelProgress();
			int num6 = instance.Level();
			float curLevel2 = num5;
			string text = instance.LevelName();
			ui.gameDone.ShowAnim(gameParams.SetWinnerIndex((!isPlayerWinner) ? 1 : 0).SetLevelNames(text, text).SetLevels(num5, curLevel2)
				.SetDelegate(delegate
				{
					GGDebug.DebugLog("Done");
					OnGameWonComplete();
				}));
		}
		GGPlayerSettings.instance.Model.shownTutorial = true;
		GGPlayerSettings.instance.Save();
		MenuParameters.InitParameters.showTrainingTutorial = !GGPlayerSettings.instance.Model.hasShownTrainingTutorial && !isPlayerWinner;
	}

	private void OnGameWonComplete()
	{
		Time.timeScale = 1f;
		BehaviourSingleton<ScreenNavigation>.instance.LoadMain(MenuParameters.MenuParams.ShowScreen.None);
	}

	public virtual void OnHitPlanAdded(SwipeToHitParams swipeParams)
	{
	}

	public virtual void OnStartServeToss()
	{
	}

	TableTennisGameTypeBase MatchControllerUiInteface.GetGameType()
	{
		return gameType;
	}

	public virtual void OnPause()
	{
		gameType.OnPause();
	}

	public virtual void OnResume(bool exit)
	{
		gameType.OnResume(exit);
	}

	public virtual void OnRematch()
	{
	}

	public virtual void OnSendMessage(string message)
	{
	}

	public virtual bool isGameWon()
	{
		return gameDone;
	}
}
